package com.cash.channel.svc.logic;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cash.channel.api.constant.Constant;
import com.cash.channel.api.exception.CashChannelException;
import com.cash.channel.api.model.cycle.AmountLimit;
import com.cash.channel.api.model.repay.*;
import com.cash.channel.api.model.repay.WdOrderInfoModel;
import com.cash.channel.svc.dao.ApplyWithdrawalFlowMapper;
import com.cash.channel.svc.model.ApplyWithdrawalFlow;
import com.geex.haneda.model.api.ApiReqModel;
import com.geex.haneda.model.api.ApiResModel;
import com.geex.haneda.service.ApiService;
import geex.core.service.LoanService;
import geex.core.service.SystemService;
import geex.core.service.model.loan.Loan;
import geex.core.service.model.loan.RepayPlan;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;


@Slf4j
@Component
public class RepayLogic {

    @Autowired(required = false)
    private ApiService hanedaApiService;

    @Autowired(required = false)
    private SystemService systemService;

    @Autowired(required = false)
    private LoanService loanService;

    @Autowired
    private OrderLogic orderLogic;

    @Autowired
    private ApplyWithdrawalFlowMapper applyWithdrawalFlowMapper;


    public List<WdOrderInfoModel> findAllWithdrawApplistByUid(String uid,String authAppId) {
        List<WdOrderInfoModel> list = new ArrayList<>();
        List<WdOrderInfoModel> AllList = new ArrayList<>();
        log.info("findAllWithdrawAppListByUidCycle, uid:" + uid);
        JSONObject requestObj = new JSONObject();
        requestObj.put("cUuid", uid);
        try {
            ApiResModel apiResModel = hanedaApiService.api(new ApiReqModel("secWDAllOrderBUAPI", requestObj.toString()));
            if (!apiResModel.getSuccess()) {
                log.error("风控端：查询提现订单列表调用失败:" + uid + "\t" + apiResModel.getErrMessage());
                return list;
            }
            log.info("secWDAllOrderBUAPI result" + apiResModel.getResult());
            net.sf.json.JSONArray jsonArray = net.sf.json.JSONArray.fromObject(apiResModel.getResult());
            if (!StringUtils.isBlank(authAppId)) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    net.sf.json.JSONObject myjObject = jsonArray.getJSONObject(i);
                    String authId = myjObject.getString("cAppId");
                    if (authAppId.equals(authId)) {
                        String wdOrders = myjObject.getString("wdOrders");
                        AllList = (List<WdOrderInfoModel>) JSONArray.parseArray(wdOrders, WdOrderInfoModel.class);
                        break;
                    }
                }
            }else{
                for (int i = 0; i < jsonArray.size(); i++) {
                    net.sf.json.JSONObject myjObject = jsonArray.getJSONObject(i);
                    String wdOrders = myjObject.getString("wdOrders");
                    list = (List<WdOrderInfoModel>) JSONArray.parseArray(wdOrders, WdOrderInfoModel.class);
                    if (org.apache.commons.collections.CollectionUtils.isNotEmpty(list)) {
                        for (WdOrderInfoModel model : list) {
                            AllList.add(model);
                        }
                    }
                }
            }

            log.info("secWDAllOrderBUAPI list model" + AllList);
        } catch (Exception e) {
            log.error("查询提现订单列表调用失败!" + e.getMessage(), e);
        }
        return AllList;
    }


    public WdOrderInfoModel findWithdrawAppInfoByAppId(String wdId) {
        WdOrderInfoModel wdOrderInfoModel = new WdOrderInfoModel();
        log.info("findWithdrawAppInfoByUid, wdId:" + wdId);
        JSONObject requestObj = new JSONObject();
        requestObj.put("cAppId", wdId);
        try {
            ApiResModel apiResModel = hanedaApiService.api(new ApiReqModel("secWDOrderBAAPI", requestObj.toString()));
            if (!apiResModel.getSuccess()) {
                log.error("风控端：查询提现订单详情调用失败:" + wdId + "\t" + apiResModel.getErrMessage());
                return null;
            }
            log.info("findWithdrawAppInfoByAppId result" + apiResModel.getResult());
            wdOrderInfoModel = JSONObject.parseObject(apiResModel.getResult(), WdOrderInfoModel.class);
            log.info("findWithdrawAppInfoByAppId model" + wdOrderInfoModel);
        } catch (Exception e) {
            log.error("查询提现订单失败!" + e.getMessage(), e);
        }
        return wdOrderInfoModel;
    }


    public List<RepayPlanModel> getRepayPlan(String cWdAppId) throws CashChannelException {

        List<RepayPlanModel>  list = new ArrayList<>();
        log.info("查询核心还款明细结果{}：",cWdAppId);
        List<RepayPlan> repayPlanList = loanService.getRepayPlanByExtId(cWdAppId);

        Date date = systemService.getSystemDate();

        if(!CollectionUtils.isEmpty(repayPlanList)){
            Loan loan = loanService.findLoanByExtId(cWdAppId);
            log.info("查询CWdAppId:{}核心还款明细结果{}：",cWdAppId , net.sf.json.JSONObject.fromObject(loan));
            Calendar canRepayCalender = Calendar.getInstance();
            canRepayCalender.setTime(loan.getLoanDate());
            for(RepayPlan repayPlan:repayPlanList){
                boolean isPaid = false;
                long time = date.getTime() - repayPlan.getPayDate().getTime();
                Integer overDays = Integer.parseInt(((String.valueOf(time / 86400000))));
                if (overDays < 0) {
                    overDays = 0;
                }
                if (repayPlan.getFinishDate() != null) {//当期是否已经结清
                    isPaid = true;
                }
                Integer overdueDay = getOverdueDay(repayPlan, overDays);
                RepayPlanModel planModel =new RepayPlanModel();
                planModel.setCurrTenor(repayPlan.getCurrTenor());
                planModel.setAllPayAmount(BigDecimal.valueOf(repayPlan.getAllPayAmount()));
                planModel.setPayDate(repayPlan.getPayDate());
                planModel.setPayTillTime(Constant.ProConstant.REPAY_TILL_TIME);
                planModel.setRemainAmount(BigDecimal.valueOf(repayPlan.getRemainAmount()));
                planModel.setOverDays(overdueDay);
                planModel.setAllPaidAmount(BigDecimal.valueOf(repayPlan.getAllPaidAmount()));
                planModel.setIsPaid(isPaid);
                planModel.setIsPaying(false);
                Double lateFee = repayPlan.getAllPayLateFee() + repayPlan.getAllPayPenalties();
                planModel.setLateFee(BigDecimal.valueOf(lateFee));
                planModel.setCorpusAmt(BigDecimal.valueOf(repayPlan.getRemainCorpus()));
                Double allPayFee =repayPlan.getAllPayFee()+repayPlan.getAllPayServiceCharge()+repayPlan.getAllPayRepayAllFee()+repayPlan.getAllPayOtherFee();
                planModel.setAllPayFee(BigDecimal.valueOf(allPayFee).setScale(2,BigDecimal.ROUND_HALF_UP));
                planModel.setAllPayCorpus(BigDecimal.valueOf(repayPlan.getAllPayCorpus()));
                planModel.setFinishDate(repayPlan.getFinishDate());
                canRepayCalender.add(Calendar.DAY_OF_MONTH, 1);
                planModel.setCanRepayDate(canRepayCalender.getTime());
                planModel.setPayType(3);
                list.add(planModel);
                canRepayCalender.setTime(repayPlan.getPayDate());
            }
        } else {
            log.error("该订单["+cWdAppId+"]暂无还款计划");
            throw new CashChannelException("该订单["+cWdAppId+"]暂无还款计划");
        }
        return list;
    }

    private Integer getOverdueDay(RepayPlan repayPlan, Integer overDays) {
        if (repayPlan.getFinishDate()==null) {
            return overDays;
        } else {
            Date payDate = repayPlan.getPayDate();
            long time = repayPlan.getFinishDate().getTime()-payDate.getTime();
            overDays = Integer.parseInt(((String.valueOf(time / 86400000))));
            return overDays<0?0:overDays;
        }
    }

    public AmountLimit getLimitAmt(String cAppId,String uid) throws Exception {
        AmountLimit amtLimit=new AmountLimit();
        Map<String,Object> orderMap = orderLogic.secQCOrderBAAPI(cAppId);
        if(orderMap!=null){
            Integer nAppAmt = MapUtils.getInteger(orderMap, "nAppAmt");
            if(null==nAppAmt){
                return amtLimit;
            }
            BigDecimal totalAmount = new BigDecimal(nAppAmt);
            BigDecimal surplusAmount = new BigDecimal(nAppAmt);

            List<WdOrderInfoModel> orderList = findAllWithdrawApplistByUid(uid,"");
            if (!CollectionUtils.isEmpty(orderList)) {
                for (WdOrderInfoModel model : orderList) {
                    Loan loanInfo = loanService.findLoanByExtId(model.getCWdAppId());
                    log.info("查询CWdAppId:{}核心还款计划{}：", model.getCWdAppId(), net.sf.json.JSONObject.fromObject(loanInfo));
                    if (loanInfo != null && !("完成".equals(loanInfo.getLoanStatus().name()) || "退货完成".equals(loanInfo.getLoanStatus().name()) || "提前还款完成".equals(loanInfo.getLoanStatus().name()))) {
                        surplusAmount = surplusAmount.subtract(model.getNWdAmt());
                    }
                }
            }
            amtLimit.setTotalAmount(totalAmount);
            amtLimit.setSurplusAmount(surplusAmount);
        }
        return amtLimit;
    }

    public ApplyWithdrawalFlow getChannelByWdId(String wdId) throws Exception {

        ApplyWithdrawalFlow flow = new ApplyWithdrawalFlow();
        flow.setcWdId(wdId);
        List<ApplyWithdrawalFlow> applyWithdrawalFlowList = applyWithdrawalFlowMapper.select(flow);
        if(!CollectionUtils.isEmpty(applyWithdrawalFlowList)){
            return  applyWithdrawalFlowList.get(0);
        }
        return null;
    }
}
